//*********************************************************************
//		Copyright (c) 2004 Microsoft Corporation.
//
// @File: xml.cs
//
// @Owner: grigoryp
//
// @Test
//
// Purpose: XML functions
//
//
//
// Notes: 
//
//
//	
// History: 
//     @Version: V1
//
//     05/25/04 PGV 1.0.001.0 Initial submission
//
// @EndHeader@
//*********************************************************************

using System;
using System.Collections;
using System.Xml;
using System.IO;


namespace H2V2.ConfigUtility
{
	public class ConfigException : Exception 
	{
		public ConfigException (string a_msg) : base (a_msg) {}
	}

	public class Configurator //: IDisposable
	{
		public ArrayList Computers_array;
		public ArrayList Perf_array;
		public string Server;
		public string Database;
		public bool bExportData;
		public bool bVerboseLogging;

		public bool IsInitialized = false;
		string m_iniFileName;
		XmlElement m_root;
		XmlDocument m_xd;

		public Configurator ()
		{
			Computers_array = new ArrayList (8);
			Perf_array = new ArrayList (2);
		}

		public void Init (string a_filename)
		{
			if (IsInitialized && m_iniFileName == a_filename) return;

			m_iniFileName = a_filename;
			//m_tr = new StreamReader (a_filename);
			m_xd = new XmlDocument ();
			m_xd.PreserveWhitespace = true;
			m_xd.Load (a_filename);
			m_root = m_xd.DocumentElement;

			IsInitialized = true;

			ReadConfig ();
		}

//		public void Close ()
//		{
//			m_xd
//		}

		public void ReadConfig ()
		{
			Computers_array.Clear ();
			Perf_array.Clear ();

			ReadRepository ();
			ReadSettings ();
			ReadTargets ();
			ReadPerfProviders ();
		}

		void ReadRepository ()
		{
			string svalue;
			XmlNode xn;
			XmlNodeList tList;

			xn = m_root.SelectSingleNode("/ROOT/REPOSITORY"); 
			tList = xn.ChildNodes;

			foreach (XmlNode tnode in tList)
			{
				switch (tnode.NodeType)
				{
					case XmlNodeType.Element:
						svalue = tnode.SelectSingleNode("attribute::Value").Value;
						//Log ("Node: "+tnode.Name+", attribute: "+svalue, EventLogEntryType.Information, 99);
					switch (tnode.Name)
					{
						case "SERVER": 
							Server = (svalue == ".") ? "<local>" : svalue;
							break;
						case "DATABASE":
							Database = svalue;
							break;
						default:
							throw new ConfigException (m_iniFileName+": Unknown node "+tnode.Name);
					}
						break;
					case XmlNodeType.Whitespace:
					case XmlNodeType.Comment:
						continue;
					default:
						throw new ConfigException (m_iniFileName+": Unexpected node type "+tnode.NodeType);
				}
			}
		}

		void ReadSettings ()
		{
			string svalue;
			XmlNode xn;
			XmlNodeList tList;

			xn = m_root.SelectSingleNode("/ROOT/SETTINGS"); 
			tList = xn.ChildNodes;

			foreach (XmlNode tnode in tList)
			{
				switch (tnode.NodeType)
				{
					case XmlNodeType.Element:
						svalue = tnode.SelectSingleNode("attribute::Value").Value;
						//Log ("Node: "+tnode.Name+", attribute: "+svalue, EventLogEntryType.Information, 99);
					switch (tnode.Name)
					{
						case "VerboseLogging":
							bVerboseLogging = (svalue.ToLower () == "true"); 
							break;
						case "ExportData":
							bExportData = (svalue.ToLower () == "true"); 
							break;
						case "DeleteFiles":
							//Constants.c_DeleteFiles = (svalue.ToLower () == "true"); 
							break;
						default:
							throw new ConfigException (m_iniFileName+": Unknown node "+tnode.Name);
					}
						break;
					case XmlNodeType.Whitespace:
					case XmlNodeType.Comment:
						continue;
					default:
						throw new ConfigException (m_iniFileName+": Unexpected node type "+tnode.NodeType);
				}
			}

			//ValidateSettings ();
		}

		void ValidateSettings ()
		{
		}

		void ReadTargets ()
		{
			string name;
			XmlNodeList tList;

			tList = m_root.SelectNodes("/ROOT/TARGET_LIST/TARGET"); 

			foreach (XmlNode tnode in tList)
			{
				name = tnode.SelectSingleNode("attribute::Name").Value.ToUpper ();
				if (name == ".")
				{
					name = Environment.MachineName.ToUpper ();
				}

				AddTarget (name);
			}

			Computers_array.TrimToSize ();
		}

		void ReadPerfProviders ()
		{
			string name;
			XmlNodeList tList;

			tList = m_root.SelectNodes("/ROOT/PERF_PROVIDERS/PERF_COLLECTOR"); 

			foreach (XmlNode tnode in tList)
			{
				name = tnode.SelectSingleNode("attribute::Name").Value.ToUpper ();
				if (name == ".")
				{
					name = Environment.MachineName.ToUpper ();
				}

				AddPerfProvider (name);
			}

			Perf_array.TrimToSize ();
		}

		public bool AddTarget (string name)
		{
			if (Computers_array.IndexOf (name) == -1) 
			{
				Computers_array.Add (name);
				return true;
			}
			return false;
		}

		public bool AddPerfProvider (string name)
		{
			if (Perf_array.IndexOf (name) == -1) 
			{
				Perf_array.Add (name);
				return true;
			}
			return false;
		}

		public void RemoveTarget (string name)
		{
			Computers_array.Remove (name);
		}
			
		public void RemovePerfProvider (string name)
		{
			Perf_array.Remove (name);
		}
			
		public void SetRepository (string a_server, string a_db)
		{
			XmlNode xn;
			XmlNodeList tList;

			xn = m_root.SelectSingleNode("/ROOT/REPOSITORY"); 
			tList = xn.ChildNodes;

			foreach (XmlNode tnode in tList)
			{
				switch (tnode.Name)
				{
					case "SERVER": 
						tnode.SelectSingleNode("attribute::Value").Value = a_server;
						break;
					case "DATABASE":
						tnode.SelectSingleNode("attribute::Value").Value = a_db;
						break;
				}
			}
		}

		public void SetSettings ()
		{
			XmlNode xn;
			XmlNodeList tList;

			xn = m_root.SelectSingleNode("/ROOT/SETTINGS"); 
			tList = xn.ChildNodes;

			foreach (XmlNode tnode in tList)
			{
				switch (tnode.Name)
				{
					case "VerboseLogging":
						tnode.SelectSingleNode("attribute::Value").Value = bVerboseLogging ? "true" : "false"; 
						break;
					case "ExportData":
						tnode.SelectSingleNode("attribute::Value").Value = bExportData ? "true" : "false"; 
						break;
				}
			}
		}

		public void Save ()
		{
			XmlWriter xw = new XmlTextWriter (m_iniFileName, null);
			m_xd.Save (xw);
		}

		public void SetTargets ()
		{
			XmlNode target;
			XmlAttribute attr;
			XmlNode tl = m_root.SelectSingleNode ("/ROOT/TARGET_LIST");
			tl.RemoveAll ();

			foreach (string s in Computers_array)
			{
				target = m_xd.CreateNode (XmlNodeType.Element, "TARGET", "");
				attr = m_xd.CreateAttribute ("Name");
				attr.Value = s.ToUpper ();
				target.Attributes.Append (attr);
				tl.AppendChild (target);
			}
		}

		public void SetPerfProviders ()
		{
			XmlNode target;
			XmlAttribute attr;
			XmlNode tl = m_root.SelectSingleNode ("/ROOT/PERF_PROVIDERS");
			tl.RemoveAll ();

			foreach (string s in Perf_array)
			{
				target = m_xd.CreateNode (XmlNodeType.Element, "PERF_COLLECTOR", "");
				attr = m_xd.CreateAttribute ("Name");
				attr.Value = s.ToUpper ();
				target.Attributes.Append (attr);
				tl.AppendChild (target);
			}
		}

	}
}





		